﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Friedlich.Common;
using DotNetOpenAuth.OAuth;
using DotNetOpenAuth.ApplicationBlock;
using System.Xml.Linq;
using DotNetOpenAuth.OAuth.ChannelElements;
using Friedlich.Web;

namespace Friedlich.Google
{
        
    public class FOAF : Friedlich.RDF.FOAF
    {
        
        private ContactList _Contacts;
        public override ContactList Contacts{
            get{
                if(_Contacts == null && _ContactProvider != null){
                    
                    //_Contacts = _new ContactList( ContactProvider.GetContacts();
                }
                return _Contacts;
            }
            set {
                _Contacts = value;
            }
        }

        private XDocument _ContactsDocument;
        public XDocument ContactsDocument {
            get{
                if (_ContactsDocument == null &&_ContactProvider != null)
                {
                    _ContactsDocument = _ContactProvider.GetContacts();
                }
                return _ContactsDocument;
            }

            set { _ContactsDocument = value; } 
        }



        private ContactProvider _ContactProvider = null;

        public FOAF(IConsumerTokenManager tokenManager, string accessToken) {

            this.TokenManager = tokenManager;
            this.AccessToken = accessToken;            
        }

        public FOAF(ContactProvider contactProvider) {
            this.TokenManager = contactProvider.TokenManager;
            this.AccessToken = contactProvider.AccessToken;
            this._ContactProvider = contactProvider;
        }

        public FOAF(XDocument contactsDocument)            
        {
            this.ContactsDocument = contactsDocument;
        }

        public FOAF() { }

        private string getAttributeValue(XElement element, string ns, string elementName, string attributeName) {
            string attrValue = string.Empty;            
            XElement elem = element.Element(XName.Get(elementName, ns));
            if (elem != null && elem.HasAttributes && elem.Attribute(attributeName) != null)
            {
                attrValue = elem.Attribute(attributeName).Value;
            }
            return attrValue;
        }



        private XDocument getContactsDocument() { 
           XDocument contactsDocument = null;           
           var google = new WebConsumer(GoogleConsumer.ServiceDescription, this.TokenManager);
           if (google != null)
            {
                if (this.AccessToken != null)
                {
                    contactsDocument = GoogleConsumer.GetContacts(google, this.AccessToken);
                }
                else {
                    var accessTokenResponse = google.ProcessUserAuthorization();
                    if (accessTokenResponse != null)
                    {
                        this.AccessToken = accessTokenResponse.AccessToken;
                    }
                }
           }
               return contactsDocument;
        }

        private ContactList getGoogleContacts() {
            ContactList contactList = new ContactList();
            
                        if(ContactsDocument != null){
                        //System.Xml.XmlWriter writer = new System.Xml.XmlTextWriter("contacts.xml", Encoding.Default);
                        //contactList.ResultXML = contactsDocument.ToString(SaveOptions.DisableFormatting);
                        //contactsDocument.Save("contacts.xml");
                        try
                        {
                            string curUserEmail = ContactsDocument.Root.GetElementValue( Namespaces.ATOM, "id");
                            foreach (var entry in ContactsDocument.Root.Elements(XName.Get("entry", "http://www.w3.org/2005/Atom"))) {
                                
                                Contact contact = null;
                                string displayName = entry.GetElementValue(Namespaces.ATOM, "title");
                                string companyName = string.Empty;
                                string jobTitle = string.Empty;
                                XElement orgEntry = entry.Element(XName.Get("organization", Namespaces.GoogleData.ToString()));                          
                                if (orgEntry != null)
                                {
                                    companyName = orgEntry.GetElementValue(Namespaces.GoogleData, "orgName");
                                    if (string.IsNullOrEmpty(displayName)) displayName = companyName;
                                    jobTitle = orgEntry.GetElementValue(Namespaces.GoogleData, "orgJobDescription");
                                }
                                
                                if(!string.IsNullOrEmpty(displayName)){
                                    contact = new Contact();
                                    contact.Name = displayName;
                                    contact.Email = getAttributeValue(entry, Namespaces.GoogleData, "email", "address");
                                    XElement nameEntry = entry.Element(XName.Get("name", Namespaces.GoogleData.ToString()));
                                    if (nameEntry != null)
                                    {
                                        contact.FirstName = nameEntry.GetElementValue(Namespaces.GoogleData, "givenName");
                                        contact.LastName = nameEntry.GetElementValue(Namespaces.GoogleData, "familyName");
                                    }

                                    contact.CompanyName = companyName;
                                    contact.JobTitle = jobTitle;

                                    IEnumerable<XElement> phoneEntries = entry.Elements(XName.Get("phoneNumber", Namespaces.GoogleData.ToString()));
                                    if (phoneEntries != null) {
                                        contact.PhoneNumbers = new List<Phone>();
                                        XElement homePhoneEntry = phoneEntries.FirstOrDefault<XElement>(x => x.GetElementRelationship().Equals(string.Concat(Namespaces.GoogleData.ToString(), "#home")));
                                        if (homePhoneEntry != null) contact.PhoneNumbers.Add(new Phone(Common.Enumerations.PhoneTypes.Home, homePhoneEntry.Value));
                                        XElement workPhoneEntry = phoneEntries.FirstOrDefault<XElement>(x => x.GetElementRelationship().Equals(string.Concat(Namespaces.GoogleData.ToString(), "#work")));
                                        if (workPhoneEntry != null) contact.PhoneNumbers.Add(new Phone(Common.Enumerations.PhoneTypes.Work, workPhoneEntry.Value));
                                        XElement cellPhoneEntry = phoneEntries.FirstOrDefault<XElement>(x => x.GetElementRelationship().Equals(string.Concat(Namespaces.GoogleData.ToString(), "#mobile")));
                                        if (cellPhoneEntry != null) contact.PhoneNumbers.Add(new Phone(Common.Enumerations.PhoneTypes.Cell, cellPhoneEntry.Value));

                                    }
                                    

                                    if (!string.IsNullOrEmpty(curUserEmail) && contact.Email.Equals(curUserEmail))
                                    {
                                        CurrentUser = contact;
                                    }
                                    else
                                    {
                                        contactList.Add(contact);
                                    }
                                }                                                                
                                
                            }
                        }
                        catch (Exception)
                        {

                            throw new NullReferenceException("ERROR");
                        }
                        
                    }
                    else throw new NullReferenceException("Contacts Document is null");
                   
            return contactList;
        }

        //private Phone getPhone(XElement phoneEntry) {
        //    Phone phone = new Phone();
        //    phone.PhoneNumber = phoneEntry.Value;
        //    string phoneType = phoneEntry.GetElementRelationship();
        //    if (!string.IsNullOrEmpty(phoneType)) { 
        //        //if(phoneType.Equals(string.Format("{0}"
        //    }
        //    return phone;
        //}

        public IConsumerTokenManager TokenManager { get; set; }

        public string AccessToken { get; set; }
    }
}
